package com.zerlings.gabeisfaker.data.retrofit

import com.dbflow5.config.DBFlowDatabase
import com.dbflow5.query.Queriable
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

object NetworkManager {

    suspend inline fun <Q : Queriable, R : Any?> DBFlowDatabase.awaitTransact(
            modelQueriable: Q,
            crossinline queriableFunction: Q.() -> R) = suspendCancellableCoroutine<R> { continuation ->
        constructCoroutine(continuation, this) { queriableFunction(modelQueriable) }
    }

    inline fun <R : Any?> constructCoroutine(continuation: CancellableContinuation<R>,
                                             databaseDefinition: DBFlowDatabase,
                                             crossinline fn: () -> R) {
        val transaction = databaseDefinition.beginTransactionAsync { fn() }
                .success { _, result -> continuation.resume(result) }
                .error { _, throwable ->
                    if (continuation.isCancelled) return@error
                    continuation.resumeWithException(throwable)
                }.build()
        transaction.execute()

        continuation.invokeOnCancellation {
            if (continuation.isCancelled) {
                transaction.cancel()
            }
        }
    }

    private val priceService = ServiceCreator.create(QueryItem::class.java)

    suspend fun queryAllPrices() = apiCall { priceService.queryAllPrices() }

    private suspend fun <T: Any> apiCall(call: suspend() -> T) : T {
        return withContext(Dispatchers.IO) { call.invoke() }.apply {
            // 特殊处理

        }
    }
}
